package com.marco.ipdata.service.impl;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.marco.commons.SpringContextUtils;
import com.marco.ipdata.runnable.BaiduApiRunnable;
import com.marco.ipdata.service.AbstractApiService;
import com.marco.ipdata.service.ChinaIPService;
import com.marco.system.service.NormalizationService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * BaiduApiServiceImpl.java
 * Create on 2017/3/22
 * Copyright(c) JD Inc 2017. All Rights Reserved.
 * <pre>
 * 功能说明：
 * </pre>
 */
@Service
@Transactional
public class BaiduApiServiceImpl extends AbstractApiService {
    private static final Logger logger = LoggerFactory.getLogger(BaiduApiServiceImpl.class);
    private static final ObjectMapper jsonParaser = new ObjectMapper();
    private static final JavaType javaType = jsonParaser.getTypeFactory().constructMapType(Map.class, String.class, String.class);
    private static final String IP_URL = "http://api.map.baidu.com/location/ip";
    private static final String TABLE_NAME = "api_ip_baidu";//百度数据存储的表名
    private static final Integer TAGS = 6;//百度接口的标记
    private static List<String> AKS;
    @Autowired
    private NormalizationService normalizationService;
    @Autowired
    private ChinaIPService chinaIPService;
    @Autowired
    private ThreadPoolTaskExecutor executor;
    // 公用线程池配置
    @Value("${executor.queue.capacity}")
    private Integer executorQueueCapacity;

    @PostConstruct
    public void AKSETS() {
        AKS = Lists.newArrayList();
        AKS.add("dOYd4yZZOWD7yjKc9bhGZuEc");
        AKS.add("IYq0mZGy3ATu9O2RIGvSmqcG");
        AKS.add("yj5kXONt3RgxCNOu2bE76W2O");
        AKS.add("ayr3xBt0tB7iezSs6ibiMyWo");
    }

    @Override
    public void obtainApiDataByParam() {
        try {
            Integer counts = chinaIPService.totalCounts();
            Double ipCountsStep = Math.ceil(counts / (AKS.size() * 1.0D));
            for (int i = 0; i < AKS.size(); i++) {
                String ak = AKS.get(i);
                BaiduApiRunnable runnable = (BaiduApiRunnable) SpringContextUtils.getBeanById("baiduApiRunnable");
                runnable.setStartIndex(ipCountsStep.intValue() * (i));
                runnable.setEndIndex(ipCountsStep.intValue() * (i + 1));
                runnable.setAk(ak);
                runnable.setThreadName("百度线程" + i);
                while (executor.getThreadPoolExecutor().getQueue().size() >= executorQueueCapacity) {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        logger.error("发送消息任务信息:线程等待出现异常", e);
                    }
                }
                executor.execute(runnable);
            }
        } catch (Exception e) {
            throw new RuntimeException("调用百度API接口出现异常", e);
        }
    }

    @Override
    protected Map<String, String> resolveResult(String result) {
        Map<String, String> res = Maps.newHashMap();
        String isp = "未知";
        String ad = "";
        try {
            //对百度返回的结果进行解析，并进行封装
            if (StringUtils.isBlank(result)) {
                res.put("isp", isp);
                res.put("ad", ad);
                return res;
            }
            Map resultMap = jsonParaser.readValue(result, Map.class);
            //状态为0表示返回正常 百度接口无国外数据
            if (resultMap.get("status") != null) {
                if (resultMap.get("status").toString().equals("0")) {
                    String[] locations = resultMap.get("address").toString().split("\\|");
                    StringBuilder sb = new StringBuilder();//中国IP
                    String nationCode = locations[0];
                    sb.append(locations[1].equals("None") ? "" : locations[1]);
                    sb.append(locations[2].equals("None") ? "" : locations[2]);
                    sb.append(locations[3].equals("None") ? "" : locations[3]);
                    if (nationCode.matches("CN|TW|HK|MO")) {
                        isp = normalizationService.formatISP(locations[4]);
                        ad = sb.toString();
                    }
                }
            }
        } catch (Exception e) {
            logger.error("解析API 返回结果出现异常", e);
        }
        res.put("isp", isp);
        res.put("ad", ad);
        return res;
    }

    @Override
    protected Logger getLogger() {
        return logger;
    }

    @Override
    protected String url() {
        return IP_URL;
    }

    @Override
    protected Integer tags() {
        return TAGS;
    }

    @Override
    protected String tableName() {
        return TABLE_NAME;
    }

}
